
#include "lwipopts.h"
#include <string.h>
#include <sys/time.h>
#include <lwip/tcp.h>


char *reply_str = "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";

uint32_t conn_num = 0;
uint32_t rx_packets_num = 0;
uint32_t rx_bytes_num = 0;


#if TEST_WITH_LOAD

void BubbleSort(unsigned char R[], int n)
{
#if 1
    char str1[40];
    int i;
    //unsigned char temp;

    char *str2 = "012345678909865432100123456789";
    memset(str1, 0, 40);

    for (i = 0; i < 50; i++)
    {
        memcpy(str1, str2, 30);
    }
#endif

#if 0
    for (i = 0; i < n - 1; i++ )
    {
        for (j = n - 2; j >= i; j--)
        {
            temp = R[j];
            R[j] = R[j + 1];
            R[j + 1] = temp;
        }
    }
#endif
}
#endif

static err_t  recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    u16_t len = 0;
    struct pbuf *q = p;

    if(p)
        len = p->tot_len;

    tcp_recved(pcb, len);

    if (p)
    {
        rx_bytes_num += len;
        while (q)
        {
            if (q->tot_len == q->len)
            {
                rx_packets_num++;
            }
            q = q->next;
        }

        //printf("got : %s\n", (char *)p->payload);

#if TEST_WITH_LOAD
        BubbleSort(p->payload, len);
#endif

        pbuf_free(p);

#if TEST_HTTP_EN
        tcp_write(pcb, reply_str, strlen(reply_str), 0);
        tcp_close(pcb);
#endif   

    }else{
        tcp_close(pcb);

    }

 

    err = ERR_OK;
    return err;

}


static err_t  accept_cb(void *arg, struct tcp_pcb *npcb, err_t err)
{

    //mch_printf("Server:new connection from %s:%d\n", ipaddr_ntoa(&npcb->remote_ip), npcb->remote_port);
    //tcp_accepted(npcb);

    conn_num ++;

    //tcp_setprio(npcb, TCP_PRIO_MIN);
    tcp_recv(npcb, recv_cb);
    /*Todo: asign this pcb to a cpu core*/

    err = ERR_OK;
    return err;

}


int server_init(struct ip_addr *ipaddr, u16_t port)
{
    struct tcp_pcb *pcb, *npcb;
    err_t err;

    pcb = tcp_new();
    if (!pcb)
    {
        mch_printf("tcp_new failed\n");
        return -1;
    }

    err = tcp_bind(pcb, ipaddr, port);
    if (err != ERR_OK)
    {
        mch_printf("tcp_bind failed\n");
        return -1;
    }

    npcb = tcp_listen(pcb);
    if (npcb == NULL)
    {
        mch_printf("tcp_listen failed\n");
        return -1;
    }

    tcp_accept(npcb, accept_cb);

    return 0;
}



